<?php

class DbMapper implements IDbMapper
{
	public $table;
	public $primary;
	public $primeAlias;
	public $fields = array();
	public $relations = array();
	public $properties = array();	
	public $fieldMaps = array();
	
	public $isString = false;
	public function __construct( array $maps = array() )
	{
		$this->_extractMap( $maps );
		$this->_validateMap();
	}
	
	protected function _validateMap()
	{
	    if( empty( $this->table ) ) throw new Exception( 'No table name specified' );
	    if( empty( $this->primary ) ) throw new Exception( 'No primary key specified' );
	    if( $this->fields === array() ) throw new Exception( 'No fields name specified' );	    
	}
	
	protected function _factory()
	{
	    return new DbMapperChain();
	}
	
	protected function _extractMap( array $maps = array() )
	{
	    $chain = $this->_factory();
	    
	    $chain->addMapper( new DbPrimaryEntity() );
	    $chain->addMapper( new DbRelationEntity() );
	    $chain->addMapper( new DbFieldEntity() );
	    
	    $chain->run( $maps, $this );
	}
}

/*
class DbMapper
{
	public $table;
	public $primary;
	public $primeAlias;
	public $fields = array();
	public $relations = array();
	public $properties = array();	
	public $fieldMaps = array();
	
	public $isString = false;
	
	const KEY_PRIMARY = 'primary';
	const KEY_RPRIMARY = 'rprimary';
	const KEY_PRIMARY_ALIAS = 'alias';
	const KEY_TABLE = 'table';
	const KEY_RTABLE = 'rtable';
	const KEY_RELATION = 'relation';
	
	const KEY_IS_STRING = 'is_string';
	const KEY_IS_FIELD = 'is_field';
	
	public function __construct( array $maps = array() )
	{
		$this->_extractMap( $maps );
		$this->_validateMap();
	}
	
	protected function _validateMap()
	{
	    if( empty( $this->table ) ) throw new Exception( 'No table name specified' );
	    if( empty( $this->primary ) ) throw new Exception( 'No primary key specified' );
	    if( $this->fields === array() ) throw new Exception( 'No fields name specified' );	    
	}
	
	protected function _extractMap( array $maps = array() )
	{
		$this->fields = array();
		foreach( $maps as $id => $val )
		{
			$this->properties[ $id ] = '';
			
			if( count( $val ) > 1 )
			{
				if( isset( $val[self::KEY_PRIMARY] ) )
				{
				    if( ! is_string( $val[self::KEY_PRIMARY] ) OR empty( $val[self::KEY_PRIMARY] ) ) 
				    {
				        throw new Exception( 'Invalid primary key specified. Only string is allowed' );
				    }
				    
				    if( ! is_string( $val[self::KEY_TABLE] ) OR empty( $val[self::KEY_TABLE] ) ) 
				    {
				        throw new Exception( 'Invalid table name specified. Only string is allowed' );
				    }
				    
					$this->primary = $val[self::KEY_PRIMARY];
					$this->primeAlias = isset( $val[self::KEY_PRIMARY_ALIAS] )? 
						$val[self::KEY_PRIMARY_ALIAS] : 
						$val[self::KEY_PRIMARY];
					
					$this->table = $val[self::KEY_TABLE];
					$this->fieldMaps[ $val[self::KEY_PRIMARY] ] = $id;
					if( isset( $val[self::KEY_IS_STRING] ) AND $val[self::KEY_IS_STRING] )
					{
						$this->isString = true;
					}
				}
				elseif( isset( $val[self::KEY_RELATION] ) )
				{
					$this->relations[ $id ] = $val;
					$this->properties[ $id ] = array();
					$this->fieldMaps[ $val[self::KEY_RELATION] ] = $id;
					if( isset( $val[self::KEY_IS_FIELD] ) )
					{
						$this->fields[] = $val['relation'];
					}
					
					if( ! isset( $this->relations[ $id ][self::KEY_RPRIMARY] ) )
					{
						$this->relations[ $id ][self::KEY_RPRIMARY] = $val[self::KEY_RELATION];
					}
				}				
			}
			else
			{		
			    $idx = array_shift( $val );
			    
			    $this->fields[] = $idx;
				$this->fieldMaps[ $idx ] = $id;
			}
		}
	}
}
*/
